home *** CD-ROM | disk | FTP | other *** search
- /* National Institute of Standards and Technology (NIST)
- /* National Computer System Laboratory (NCSL)
- /* Office Systems Engineering (OSE) Group
- /* ********************************************************************
- /* D I S C L A I M E R
- /* (March 8, 1989)
- /*
- /* There is no warranty for the NIST NCSL OSE SGML parser and/or the NIST
- /* NCSL OSE SGML parser validation suite. If the SGML parser and/or
- /* validation suite is modified by someone else and passed on, NIST wants
- /* the parser's recipients to know that what they have is not what NIST
- /* distributed, so that any problems introduced by others will not
- /* reflect on our reputation.
- /*
- /* Policies
- /*
- /* 1. Anyone may copy and distribute verbatim copies of the SGML source
- /* code as received in any medium.
- /*
- /* 2. Anyone may modify your copy or copies of SGML parser source code or
- /* any portion of it, and copy and distribute such modifications provided
- /* that all modifications are clearly associated with the entity that
- /* performs the modifications.
- /*
- /* NO WARRANTY
- /* ===========
- /*
- /* NIST PROVIDES ABSOLUTELY NO WARRANTY. THE SGML PARSER AND VALIDATION
- /* SUITE ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
- /* EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- /* THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
- /* WITH YOU. SHOULD THE SGML PARSER OR VALIDATION SUITE PROVE DEFECTIVE,
- /* YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
- /*
- /* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL NIST BE LIABLE FOR
- /* DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
- /* INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
- /* INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
- /* BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
- /* FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
- /* NIST) THE PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
- /* SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
- */
-
- /************************************************************************/
- /* TITLE: SGML PARSER */
- /* SYSTEM: DTD PROCESSOR */
- /* SUBSYSTEM: */
- /* SOURCE FILE: DETUTIL.C */
- /* AUTHOR: Michael Garris */
- /* */
- /* DATE CREATED: */
- /* LAST MODIFIED: */
- /* */
- /* REVISIONS */
- /* WHEN WHO WHY */
- /************************************************************************/
- #include <stdio.h>
- #include "detdefs.h"
- #include "detglbl.h"
- char *malloc();
- /************************************************************************/
- /************************************************************************/
- /* NESTLEVEL inputs an expression at "iptr" and calculates the number of*/
- /* nested levels of "()" in the expression, returning the calculation */
- /************************************************************************/
- int nestlevel(iptr)
- register ITEM *iptr;/* points to the expression */
- {
- register int nest = 0;/* nest level */
- register int cntr = 0;/* current level */
-
- /* if iptr is not at a GRPO then a synchronization error has occurred */
- if(iptr++->itoken != GRPO){
- return(0);
- }
- /* otherwise a GRPO has been found and the nesting level gets bumped */
- ++nest;
- /* also a counter gets bumped for each GRPO found and decremented */
- /* for each GRPC found */
- ++cntr;
- /* while the counter is not 0 ==> not at the end of the expression ...*/
- while(cntr > 0){
- /* while neither a GRPO or a GRPC has been found ...*/
- while((iptr->itoken != GRPO) && (iptr->itoken != GRPC)){
- /* if a FSAid pointer is found in the expression, skip it */
- if(iptr->itoken == POINTER){
- /* invokes a procedure which moves iptr the size of a pointer */
- /* commented out by Michael D. Garris on 11/23/87 */
- /* due to the introduction of ITEM type */
- /* skippointer(&iptr); */
- iptr += 2;
- continue;
- }
- /* if not a pointer, GRPO, or GRPC then skip it */
- ++iptr;
- }
- /* if a GRPO is found ... */
- if(iptr->itoken == GRPO){
- /* bump the nesting level */
- ++nest;
- /* bump the current level */
- ++cntr;
- }
- /* if a GRPC is found ... */
- if(iptr->itoken == GRPC){
- /* decrement the current level */
- --cntr;
- }
- /* continue looking in the expression */
- ++iptr;
- }
- /* once the end of the expression is found, then return the */
- /* value in nestin level */
- return(nest);
- }
- /************************************************************************/
- /************************************************************************/
- /* GETLOWGRP takes an expression and scans it left to right until "nest"*/
- /* number of "(" have been found, setting the expression pointer to that*/
- /* location */
- /************************************************************************/
- void getlowgrp(ptrin, nest)
- ITEM **ptrin;
- register int nest;
- {
- register ITEM *iptr = *ptrin;
- register int i;
-
- for(i = 0; i < nest; ++i){
- while(iptr++->itoken != GRPO);
- }
- *ptrin = --iptr;
- }
- /************************************************************************/
- /************************************************************************/
- /* SKIPPOINTER takes a pointer to a FSAid in an expression and moves the*/
- /* pointer to just past the FSAid pointer */
- /************************************************************************/
- void skippointer(ptrin)
- ITEM **ptrin;
- {
- register ITEM *iptr = *ptrin;
-
- /* bump iptr by the size of a token, skipping the "-1" which */
- /* is in font of all FSAid pointers in the expression */
- ++iptr;
- /* increment iptr the size of a pointer, skipping the actual */
- /* FSAid pointer*/
- ++iptr;
- *ptrin = iptr;
- }
- /************************************************************************/
- /************************************************************************/
- /* GETTOKEN inputs a pointer to a token in an expression and returns the*/
- /* token, extracting the space occupied by the token from the expression*/
- /************************************************************************/
- int gettoken(iptr)
- register ITEM *iptr;
- {
- register int token;
-
- /* if iptr is pointing to a valid token ...*/
- if((iptr->itoken > 0x10) && (iptr->itoken < 0xFF))
- /* then assign token what iptr is pointing to */
- token = iptr->itoken;
- else
- /* otherwise a synchronization error has occurred */
- myexit(1,"Token not found in group");
- /* invokes a procedure which removes the space the size of an int */
- /* from the expression at iptr */
- stripunit(INT,iptr);
- /* returns the token */
- return(token);
- }
- /************************************************************************/
- /************************************************************************/
- /* GETOCCIND takes a pointer to an occurance indicator in an expression */
- /* and returns the occurance indicator, extracting the space occupied */
- /* by the occurance indicator from the expression . */
- /************************************************************************/
- int getoccind(iptr)
- ITEM *iptr;
- {
- int occind;
-
- switch(iptr->itoken){
- /* if iptr points to an optional occurance indicator ...*/
- case OPT:
- occind = OPT;
- break;
- /* if iptr points to an optional-repeatable occ. indicator ...*/
- case REP:
- occind = REP;
- break;
- /* if iptr points to a required-repeatable occ. indicator ...*/
- case PLUS:
- occind = PLUS;
- break;
- /* if iptr points to a required occurance indicator ... */
- case REQ:
- occind = REQ;
- break;
- }
- /* invokes a procedure which removes the space the size of an int */
- /* from the expression at iptr */
- stripunit(INT,iptr);
- /* return the occurance indicator */
- return(occind);
- }
- /************************************************************************/
- /************************************************************************/
- /* BUILDSTATE allocates memory for a structure called a state, returning*/
- /* a pointer to the allocated memory and setting all components of the */
- /* structure to NULL. */
- /* A state is made of a left and right pointer pointing to other state */
- /* structures, a left and right label marking each respective pointer, */
- /* and a left and right instance number for each respective label. */
- /************************************************************************/
- STATE *buildstate()
- {
- register STATE *state;/* pointer memory will be allocated to */
-
- /* allocate memory to "state" the size of a state structure */
- state = mymalloc(sizeof(STATE));
- /* if malloc returned 0 then a memory allocation has occurred */
- if(state == 0)
- myexit(1, "Memory allocation error");
- /* set all the fields of the components of the structure to NULL */
- state -> lptr = NULL;
- state -> llabel = NULL;
- state -> linst = NULL;
- state -> rptr = NULL;
- state -> rlabel = NULL;
- state -> rinst = NULL;
- /* return a pointer to the allocated memory */
- return(state);
- }
- /************************************************************************/
- /************************************************************************/
- /* BUILDID allocates memory to a structure called a FSAid, returning a */
- /* pointer to the allocated memory and setting all components of the */
- /* structure to NULL. */
- /* A FSAid is made of two pointers to state structures. The startptr */
- /* points to the start state of an FSA, and the finalptr points to the */
- /* final state of the same FSA. */
- /************************************************************************/
- STATEID *buildid()
- {
- register STATEID *stateid;
-
- /* allocate memory the size of a FSAid structure to the */
- /* pointer "stateid" */
- stateid = (STATEID *)malloc(sizeof(STATEID));
- /* if malloc returns 0 then a memory allocation error occurred */
- if(stateid == 0)
- myexit(1,"Memory allocation error");
- /* set both pointers of the FSAid structure to NULL */
- stateid -> startptr = NULL;
- stateid -> finalptr = NULL;
- /* return the pointer to the allocated memory */
- return(stateid);
- }
- /************************************************************************/
- /************************************************************************/
- /* INSERTPOINTER takes a pointer to a location within an expression and */
- /* inserts space for the inputted FSAid, placing the FSAid into the */
- /* expression. */
- /************************************************************************/
- void insertpointer(ptrin,stateid)
- ITEM **ptrin;
- STATEID *stateid;
- {
- register ITEM *iptr = *ptrin;
-
- /* invoke procedure to insert space the size of an int into */
- /* the expression at location iptr */
- makeroom(INT,iptr);
- /* place a "-1" flagging, FSAid pointer following, */
- /* into the expression */
- iptr++->itoken = POINTER;
- /* invokes a procedure to insert space the size of a FSAid */
- /* pointer into the expression */
- makeroom(PTR,iptr);
- /* place the FSAid pointer into the expression */
- iptr++->ptoken = stateid;
- *ptrin = iptr;
- }
- /************************************************************************/
- /************************************************************************/
- /* MAKEROOM takes a pointer to an expression and insets space the size */
- /* indicated by "type" at the location of the pointer. */
- /************************************************************************/
- void makeroom(type,iptr)
- int type;
- ITEM *iptr;
- {
- int dif;
- register int j;
- register char *src, *dest;
- char temp[400];
-
- /* assign "dif" the difference from the current location */
- /* in the expression "iptr" to the end of the expression */
- j = dif = (endbuf - iptr) * sizeof(ITEM);
- /* move the section of expression from the current pointer on */
- /* to the right the distance of "size" */
- src = (char *) iptr;
- dest = temp;
- while (j--)
- *dest++ = *src++;
- src = temp;
- dest = (char *)(iptr + 1);
- while(dif--)
- *dest++ = *src++;
- #ifdef OLD
- memcpy((char *)(iptr + 1), (char *)iptr, dif);
- #endif
- /* calculate a new end of expression */
- endbuf++;
- }
- /************************************************************************/
- /************************************************************************/
- /* FINDENDOFGRP takes a pointer to the current location in an expression*/
- /* along with the current number of nested levels and scans to the right*/
- /* of the pointer until the end of the expression is found, retruning */
- /* a pointer to the end of the expression. */
- /************************************************************************/
- ITEM *findendofgrp(iptr,nest)
- register ITEM *iptr;
- int nest;
- {
- register int cntr;/* will be the current level of nesting */
-
- /* assign "cntr" the current level of nesting */
- cntr = nest;
- /* while current level of nesting is > 0 ==> not end of expression ...*/
- while(cntr > 0){
- /* while neither a GRPO or a GRPC is found ...*/
- while((iptr->itoken != GRPO) && (iptr->itoken != GRPC)){
- /* if iptr is pointing to an FSAid pointer ...*/
- if(iptr->itoken == POINTER){
- /* invokes a procedure to move the expression pointer */
- /* just past the FSAid pointer */
- iptr += 2;
- /* changed by Michael D. Garris 11/23/87 */
- /* commented out with the addition of ITEM type */
- /* skippointer(&iptr); */
- continue;
- }
- /* continue looking right in expression */
- ++iptr;
- }
- /* if GRPO found ...*/
- if(iptr->itoken == GRPO){
- /* bump nesting level and current nesting level */
- ++nest;
- ++cntr;
- }
- /* if GRPC found ...*/
- if(iptr->itoken == GRPC){
- /* decrement current nesting level */
- --cntr;
- }
- /* continue scanning to the right */
- ++iptr;
- }
- /* return pointer to end of expression */
- return(iptr+1);
- }
- /************************************************************************/
- /************************************************************************/
- /* STRIPUNIT takes a pointer to an expression and removes a location the*/
- /* size indicated by "type" from the expression at the pointer */
- /************************************************************************/
- void stripunit(type,iptr)
- int type;
- ITEM *iptr;
- {
- int dif;
-
- /* assign "dif" the difference from the current expression */
- /* pointer to the end of the expression */
- dif = (endbuf - iptr + 1) * sizeof(ITEM);
- /* move the section of expression from the current pointer plus */
- /* the size of the unit being stripped on to the current pointer*/
- memcpy((char *)iptr,(char *)(iptr + 1),dif);
- /* calculate a new end of expression pointer */
- endbuf -= 1;
- }
- /************************************************************************/
- /************************************************************************/
- /* COPY takes a section of expression at "scr" of length "len" and moves*/
- /* it to location "dest" in the expression. */
- /************************************************************************/
- void copy(dest,src,len)
- register char *dest,*src;
- register int len;
- {
- /* if section being moved is to the right of the destination ...*/
- if(src >= dest){
- /* while "length" units have not yet been moved ...*/
- while((len--) > 0){
- /* copy contents of source to destination and continue */
- *dest++ = *src++;
- }
- }
- /* otherwise section being moved is to the left of the destination */
- /* and a left to right transfer of contents could result in valid */
- /* data being over-written */
- else{
- /* if destination is to the right of the source ...*/
- if(dest > src)
- /* while "length" units have not yet been move ...*/
- while(len-- > 0){
- /* copy contents of source to destination right to left */
- /* from the end of the source */
- *(dest + len) = *(src + len);
- }
- }
- }
- /************************************************************************/
- /************************************************************************/
- /* GETCONNECTOR inputs a pointer to a connector in an expression and */
- /* returns the connector, extracting the space occupied by the connector*/
- /* from the expression. */
- /************************************************************************/
- int getconnector(iptr)
- ITEM *iptr;
- {
- int connector;
-
- /* assign "connector" the contents of the expression pointer */
- connector = iptr->itoken;
- /* invokes a procedure to extract the space of an int from */
- /* the expression at location "iptr"*/
- stripunit(INT,iptr);
- /* returns the connector */
- return(connector);
- }
- /************************************************************************/
- /************************************************************************/
- /* MYEXIT inputs an error code and an error message, printing the */
- /* message and exiting on the error code. */
- /************************************************************************/
- void myexit(code,msg)
- int code;
- char *msg;
- {
- printf("%s\n",msg);
- exit(code);
- }
- /************************************************************************/
- /************************************************************************/
- /* SEARCHTOKEN searches a list of tokens,"tokseen", for matches on the */
- /* value "token", returning the number of matches which occurred. */
- /************************************************************************/
- int searchtoken(token,tokseen,tokptr)
- register int token;
- ITEM *tokseen,*tokptr;
- {
- register ITEM *ptr = tokseen;/* set "ptr" to beginning of token list */
- int inst = 0;/* will be the number of matches which occur */
-
- /* while not end of the token list ...*/
- while(ptr != tokptr){
- /* if a match on the "token" occurs...*/
- if(ptr++->itoken == token)
- /* bump the instance counter */
- ++inst;
- }
- /* return the number of matches */
- return(inst);
- }
- /************************************************************************/
- /************************************************************************/
- /****** M Y M A L L O C *************************************************/
- /* this will create a linked list to track all malloc's ****************/
- /************************************************************************/
- STATE *mymalloc(size)
- int size;
- {
- STATE *statetemp;
- register MEMNODE *memtemp,*curmem;
- curmem = head;
- if ((statetemp = (STATE *)malloc(size)) == NULL) {
- printf("Memory Allocation Error\n");
- exit(99);
- }
- if ((memtemp = (MEMNODE *)malloc(sizeof(MEMNODE))) == NULL) {
- printf("Memory Allocation Error\n");
- exit(99);
- }
- (*memtemp).stateptr = statetemp;
- (*memtemp).memnodeptr = NULL;
- if ( head == NULL )
- head = memtemp; /* head is null; first time thru */
- else {
- while ( (*curmem).memnodeptr != NULL )
- curmem = (*curmem).memnodeptr; /* find the end of list */
- (*curmem).memnodeptr = memtemp;
- }
- return((*memtemp).stateptr);
- }
- /************************************************************************/
- /** F R E E F S A *******************************************************/
- /************************************************************************/
- freeFSA()
- {
- register MEMNODE *curmem,*temp;
-
- curmem = head;
- if ( head == NULL )
- return;
- while ( curmem != NULL ){
- temp = (*curmem).memnodeptr;
- free((char *) ((*curmem).stateptr));
- free((char *) curmem);
- curmem = temp;
- }
- }
- /************************************************************************/
-
-